/*
 * Created on 2005-5-16
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.haoxi.gateway.runner;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.haoxi.gateway.common.Queue;

/**
 * @author Cloud
 * Preferences - Java - Code Style - Code Templates
 */

public abstract class AbsIntoQueue implements IRun {
    /**
     * Logger for this class
     */
    private static final Log log = LogFactory
            .getLog(AbsIntoQueue.class);
    
    /**
     * display name
     */
    private static String MY_NAME = "AbsIntoQueue";
    
    public static final int ACTION_NORMAL = 2;
    
    public static final int ACTION_ERROR = 4;
    
    public static final int ACTION_SLEEP = 8;
    
    /**
     * union queue
     */
    private static Queue queue;
    
    private boolean running = false;
    private int run_stat = IRun.RUNNER_READY;
    
    private Date createTime;
    private Date lastRunTime;
    private long sleepTime = 5000;
    
    private long perLunSleep = 10;
    
    private String name = MY_NAME;
    
    public AbsIntoQueue(Queue toQueue) {
        queue = toQueue;
        
        createTime = new Date();
    }
    
    public void run() {
        log.debug("Into Queue:" + name + " start !!!");
        
        //check conn
        if(queue == null) {
            return;
        }
        
        running = true;
        lastRunTime = new Date();
        int nAction = ACTION_SLEEP;
        while (running) {
            run_stat = IRun.RUNNER_RUNNING;
            lastRunTime.setTime(System.currentTimeMillis());
            
            nAction = ACTION_SLEEP;
            try {
                
                //if the current len more then  3/4 of MAX, sleep
                if(!checkCanIntoQueue()) {
                    run_stat = IRun.RUNNER_WAITING;
                    Thread.sleep(sleepTime);
                    continue;
                } else {
                    
                    /////////////user actin////////////
                    nAction = doJob();
                    if(nAction == ACTION_NORMAL) {
                        continue;
                    } else if(nAction == ACTION_SLEEP) {
                        Thread.sleep(sleepTime);
                    } else {
                        log.error("action ERROR !!!!!!");
                    }
                    
                }
            } catch (Exception e) {
                log.error("other Exception", e);
            } finally {
                try {
                    Thread.sleep(perLunSleep);
                } catch (InterruptedException e) {
                    log.error("InterruptedException", e);
                }
            }
        }//end of while
        running = false;
        run_stat = IRun.RUNNER_DEAD;
        
        log.debug("Into Queue:" + name + " ended !!!");
    }
    
    abstract public int doJob();
    
    /**
     * check the object can into queue
     * @return true is can
     */
    protected boolean checkCanIntoQueue() {
        if(queue == null) {
            return false;
        }
        int nLen = queue.getLength();
        if(nLen*4/3 >= queue.getMaxLength()) {
            return false;
        } else {
            return true;
        }
    }
    
    public Date getCreateTime() {
        return createTime;
    }

    public Date getLastRunTime() {
        return lastRunTime;
    }

    public long getSleepTime() {
        return sleepTime;
    }

    public int getStatus() {
        return run_stat;
    }

    public boolean isRunning() {
        return running;
    }

    public void setSleepTime(long lsleepTime) {
        sleepTime = lsleepTime;
    }

    public void setStop() {
        running = false;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static Queue getQueue() {
        return queue;
    }
}
